Service Class
#WIP
Service Classってなんやねん
独自の状態を持たない
結果として、特定のドメインのutil関数群みたいな感じになる?
手続の集合
実行する操作以外にドメインにおいて意味を持たない
逆に言えば、そういう中途半端なものをServiceに追いやる
名詞というよりは動詞で表現する方が近い
らしい
あまりピンときていないmrsekut.icon
責務
Controllerに対して業務ロジックを提供する
Usecase Interactor的な?
business logicに関わる処理の実装に専念する
業務データの参照および更新処理をRepositoryに委譲する
業務ロジック内で必要となる業務データは、Repositoryを介して、Entityオブジェクトとして取得する
業務ロジックを実行するためのメソッドを実装し、アプリケーション層に提供する
トランザクション境界を宣言する。
データの一貫性を保障する必要がある処理を行う業務ロジックの場合、トランザクション境界を宣言する
DDDの4層のレイヤー例の各レイヤーにServiceは存在しうる
そして、これらを明確に分離すべきとEric Evansは主張している
ドメインサービス
アプリケーションサービス
インフラストラクチャサービス
例 ref 『エリック・エヴァンスのドメイン駆動設計』.icon pp.105-106
「技術的」って訳すの意味不明では?
utility関数群的ってこと?
Symfonyのディレクトリ構造は、これを表現しにくくないか #??
だとしたらEntityディレクトリと並列にServiceディレクトリを置くべきではないな
言わずもがなPackage by Layerになっている前提で(Framework的に)
Entityディレクトリや、Controllerディレクトリ内に含めるべきだと思う
もしくはドメインサービスディレクトリやアプリケーションサービスディレクトリを作るか
あまりにもPBLすぎるので避けたい
https://qiita.com/os1ma/items/25725edfe3c2af93d735#サービスも-2-種類ある
Serviceのクラス構成 ref
Service Class
特定のControllerに対してbusiness logicを提供する。
故に各medhodは、再利用を考慮したロジックは実装しない
SharedService Class
複数のControllerやService Classで、共有されるロジックを提供する
この2つををディレクトリ構造として分けるべきではない気がしているが、どうなんだろうmrsekut.icon
ここに書いてる「ドメインサービス」と「アプリケーションサービス」の対応は #??
そのままドメインサービス==Service Classとは対応できなさそうだが
Application Service
ドメインオブジェクトを使ってアプリケーションの要求を実現する
ドメインモデル内のビジネスロジックには立ち入らず、「タスクの調整」に留める
こっちの方がUsecase Interactorっぽい
Domain Serviceと比較して
複数noEntityと接続したり、Repository、Controllerと遣り取りをする
かなり頻繁につかう
Domain Service
特定のEntityに対するService
Enittyに書きづらいけど、特定のEntityの為の処理を書く場所
https://nrslib.com/bottomup-ddd/#outline__3_3
たまに使う
この線引の仕方だと、「どのEntityにも依存しないような汎用的なオブジェクト」の為のサービスってどこに書くんや #??
https://system.blog.uuum.jp/entry/using-service-class
コンストラクタでのみ依存関係を解決する
原則としてコンストラクタで注入された依存以外の状態を持たない(キャッシュ用などで持つ場合はある)
インスタンスメソッドが複数あり、インスタンスメソッドの結果は引数と依存関係によってのみ決まる(時刻とかが含まれる場合は別途)
#??
ここでもDomainObjectの更新はするよね?
アプリケーションのビジネスロジック
アプリケーションってなに?
Serviceは外部サービスを接続していいのか
つまりControllerの中でrequestを送っていいのか
DBなどと接続したりしてもいいの?
あるいはRepository ClassをService内から呼び出していいのか
参考
4.1. ドメイン層の実装 — TERASOLUNA Global Framework Development Guideline 1.0.0.publicreview documentation
今のmrsekut.iconの理解としては、
OOPが前提にある
故に全てはデータ構造ではなく、オブジェクトである
つまりfunction-orientedとは根幹が異なる
イメージしやすいlodashみたいな汎用便利関数モジュールみたいなのは存在しない
だから「画像一般をゴニョる汎用便利関数群」みたいなのがほしければ
Image Class的なやつを作って使う
だからこんな感じになる
code:イメージ.ts
const url = '~~~~.png'
// こうじゃなくて
const fop = isImage(url);
// こう
const oop = new Image();
const isImage = oop.isImage(url);
じゃあこのImage classってディレクトリ構造のどこに置くねん、という話になる
DDDで言う「Enity」って「ビジネスに関与したオブジェクト」のことだと思ってる
例えばUserとかItemとか
しかし、今問題になっているImageはもっと汎用的なオブジェクトである
だからこの2つの概念を並列に扱うべきではない(とDDDは考えてるんじゃないかな、と、mrsekut.iconは思っている)
しかし、/mrsekut-b/Componentsのディレクトリ構造をどうするかの考え方をするなら、ビジネス関与と、そうでないオブジェクトを区別する必要もない、とも感じる
このゴニョりは、全てを同列にレイヤードにしようとしてることから生じている
そこでServiceという概念が存在する(?)
という理解をしている
わかったわかった
SharedServiceだmrsekut.icon*4
次は、Imageは、ValueObjectなのかServiceなのか、で迷い始めた
そもそも状態を持つ必要性がないからServiceか
#??
というのを前提した時に、ImageについてのClassを作るなら、その中で通信とかしちゃってもいいのか?
参考
『エリック・エヴァンスのドメイン駆動設計』 p.103~
https://torazuka.hatenablog.com/entry/20110127/service
https://www.slideshare.net/ssuser21f9f1/ss-91855744
/mrsekut-book-477419087X/153 (ドメインオブジェクトを使って機能を実現する)